package com.tanhua.manage.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.unit.DataUnit;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanhua.manage.domain.AnalysisByDay;
import com.tanhua.manage.mapper.AnalysisMapper;
import com.tanhua.manage.mapper.LogMapper;
import com.tanhua.manage.utils.ComputeUtil;
import com.tanhua.manage.vo.AnalysisDataVo;
import com.tanhua.manage.vo.AnalysisSummaryVo;
import com.tanhua.manage.vo.AnalysisUsersVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class AnalysisService extends ServiceImpl<AnalysisMapper,AnalysisByDay> {


    @Autowired(required = false)
    private LogMapper logMapper;









    /**
     * 统计概要信息
     * @return
     */
    public ResponseEntity<Object> summary() {
        //1. 统计今天数据
        Date now = new Date();
        String nowDate = DateUtil.format(now,"yyyy-MM-dd");
        //1.1 累计用户
        AnalysisByDay analysisByDay = query().select("SUM(`num_registered`) as numRegistered").one();
        Integer cumulativeUsers = analysisByDay.getNumRegistered();

        //1.2 查询今日新增用户, 登陆次数, 活跃用户
        AnalysisByDay analysisByDayToday = query().eq("record_date", nowDate).one();
        Integer numRegisteredToday = analysisByDayToday.getNumRegistered();
        Integer numLoginToday      = analysisByDayToday.getNumLogin();
        Integer numActiveToday     = analysisByDayToday.getNumActive();

        //2. 统计昨天的数据
        String yesterday = ComputeUtil.offsetDay(now, -1);
        AnalysisByDay analysisByDayYes = query().eq("record_date", yesterday).one();
        Integer numRegisteredYes = analysisByDayYes.getNumRegistered();
        Integer numLoginYes    = analysisByDayYes.getNumLogin();
        Integer numActiveYes     = analysisByDayYes.getNumActive();

        //过去7天与30天的活跃用户
        long day7 = this.getBaseMapper().findNumActiveByDate(ComputeUtil.offsetDay(now,-7),nowDate);
        long day30 = this.getBaseMapper().findNumActiveByDate(ComputeUtil.offsetDay(now,-30),nowDate);


        //3. 把数据封装到Vo对象中返回即可
        AnalysisSummaryVo vo = new AnalysisSummaryVo();
        vo.setCumulativeUsers(cumulativeUsers.longValue()); //累计用户
        vo.setActivePassMonth(day30); //过去30天
        vo.setActivePassWeek(day7); //过去7天
        vo.setNewUsersToday(numRegisteredToday.longValue()); //今日新增用户
        vo.setNewUsersTodayRate(ComputeUtil.computeRate(numRegisteredToday,numRegisteredYes)); // 今日新增用户环比率
        vo.setLoginTimesToday(numLoginToday.longValue()); //今日登陆次数
        vo.setLoginTimesTodayRate(ComputeUtil.computeRate(numLoginToday,numLoginYes));
        vo.setActiveUsersToday(numActiveToday.longValue()); //今日活跃用户
        vo.setActiveUsersTodayRate(ComputeUtil.computeRate(numActiveToday,numActiveYes));
        return ResponseEntity.ok(vo);
    }

    //作用分析日志表，把日志表的数据插入到日表中
    public void anasysis() {
        //1. 查看当前日表中有没有今天记录
        String now = DateUtil.formatDate(new Date());//yyyy-MM-dd
        AnalysisByDay analysisByDay = query().eq("record_date", now).one();

        //2. 如果没有今天记录，就插入今天的记录数据，
        if(analysisByDay==null){
             analysisByDay =new AnalysisByDay();
             analysisByDay.setRecordDate(new Date());
             analysisByDay.setCreated(new Date());
             analysisByDay.setUpdated(new Date());
             this.save(analysisByDay);
        }
        String yesterday= ComputeUtil.offsetDay(new Date(), -1);
        //3.查询日志表得到 今日注册人数、登陆人数、活跃人数、次日保留人数
        Long loginNum = logMapper.queryNumsByType(now, "0101"); //登陆人数
        Long  regNum= logMapper.queryNumsByType(now, "0102"); //登陆人数
        Long  activeNum= logMapper.queryNumsByDate(now); //活跃人数
        Long  retentNum= logMapper.queryRetention1d(now,yesterday); //登陆人数

        //4. 更新日表的数据
        analysisByDay.setNumRegistered(regNum.intValue());
        analysisByDay.setNumActive(activeNum.intValue());
        analysisByDay.setNumLogin(loginNum.intValue());
        analysisByDay.setNumRetention1d(retentNum.intValue());
        analysisByDay.setUpdated(new Date());
        this.updateById(analysisByDay);
    }







    /**
     * 接口名称：新增、活跃用户、次日留存率
     */
    public ResponseEntity<Object> queryAnalysisUsers(Long sd, Long ed, Integer type) {
        /**今年
         * 获取开始时间对应的日期字符串*/
        String startDate = new SimpleDateFormat("yyyy-MM-dd").format(sd);
        /**获取结束时间对应的日期字符串*/
        String endDate = new SimpleDateFormat("yyyy-MM-dd").format(ed);
        /**今年开始到结束的查询数据*/
        List<AnalysisDataVo> thisYear = queryAnalysisDataVo(startDate, endDate, type);

        /**去年
         * 获取
         * 开始时间
         * 对应去年开始的日期字符串*/
        Calendar instance = Calendar.getInstance();
        instance.setTime(new Date(sd));
        instance.add(Calendar.YEAR,-1);/**日期减1年*/
        Date lastYearStartDate = instance.getTime();
        String lastYearStartDates = new SimpleDateFormat("yyyy-MM-dd").format(lastYearStartDate);

        /**
        *获取
         * 结束时间
         * 对应去年的结束日期字符串*/
        instance.setTime(new Date(ed));
        instance.add(Calendar.YEAR,-1);/**日期减1年*/
        Date lastYearEndDate = instance.getTime();
        String lastYearEndDates= new SimpleDateFormat("yyyy-MM-dd").format(lastYearEndDate);
        /**去年开始到结束的查询数据*/
        List<AnalysisDataVo> lastYear = queryAnalysisDataVo(lastYearStartDates, lastYearEndDates, type);

        /**创建构造返回给前端的Vo*/
        AnalysisUsersVo analysisUsersVo = new AnalysisUsersVo(thisYear, lastYear);
        return ResponseEntity.ok(analysisUsersVo);
    }


    /**公共方法*/
    public List<AnalysisDataVo> queryAnalysisDataVo(String startDate, String endDate, Integer type) {
        /**获取起始时间和结束时间之间的所有AnalysisByDay数据*/
        List<AnalysisByDay> analysisByDayList = query().ge("record_date", startDate).le("record_date", endDate).list();
        /**创建构造要返回的每日数据点集合*/
        List<AnalysisDataVo> analysisDataVoList = new ArrayList<>();


        for (AnalysisByDay analysisByDay : analysisByDayList) {
            AnalysisDataVo analysisDataVo = new AnalysisDataVo();
            analysisDataVo.setTitle(new SimpleDateFormat("yyyy-MM-dd").format(analysisByDay.getRecordDate()));

            /**
             * 查询类型
             * 101 新增
             * 102 活跃用户
             * 103 次日留存率
             *
             * */
            switch (type) {
                case 101:
                    analysisDataVo.setAmount(analysisByDay.getNumRegistered());  //新注册的
                    break;
                case 102:
                    analysisDataVo.setAmount(analysisByDay.getNumActive());  //活跃的
                    break;
                case 103:
                    analysisDataVo.setAmount(analysisByDay.getNumRetention1d());  //次日留存率
                    break;
            }
           /**
            * 把每日数据点添加到要返回的每日数据点集合*/
            analysisDataVoList.add(analysisDataVo);
        }

        return analysisDataVoList;
    }
}




